package com.budwk.app.sqfw.component;


import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.common.config.AppException;
import com.budwk.app.jim.SqfwWebSocket;
import com.budwk.app.jim.WebSocketMsgDTO;
import com.budwk.app.sqfw.dto.SqfwCompleteFlowUpdateDTO;
import com.budwk.app.sqfw.dto.SqfwFormSummaryWithFlowDTO;
import com.budwk.app.sqfw.enums.SqfwFormSummaryFieldEnum;
import com.budwk.app.sqfw.enums.SupportBusinessTypeEnum;
import com.budwk.app.sqfw.models.Sqfw_cenSusPaper;
import com.budwk.app.sqfw.models.Sqfw_completeflow;
import com.budwk.app.sqfw.models.Sqfw_formSummary;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfw.services.SqfwCenSusPaperService;
import com.budwk.app.sqfw.services.SqfwCompleteflowService;
import com.budwk.app.sqfw.services.SqfwFormSummaryService;
import com.budwk.app.sqfw.services.SqfwWorkorderService;
import com.budwk.app.sqfw.vo.GenerateWordAndPdfUrlVO;
import com.budwk.app.sqfw.vo.template.MeetingMinutesTemplateVo;
import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.BasePdfParamDTO;
import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.SqfwPdfCreateCommonBO;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.CommonParam;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.PdfGenerateParam;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.util.StrUtil;
import com.budwk.app.util.poiUtils.CommonFormOfficeUtils;
import com.budwk.app.util.poiUtils.excelPictureConfigBO.ExcelFileCreateParamBO;
import com.budwk.app.util.poiUtils.excelPictureConfigBO.HouseSurveyFormExcelSNSQ;
import com.budwk.app.util.poiUtils.excelPictureConfigBO.MeetFormExcelSNSQ;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import com.budwk.starter.security.utils.SecurityUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nutz.aop.interceptor.async.Async;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.trans.Trans;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

import static com.budwk.app.util.poiUtils.CommonFormOfficeUtils.createExcelAndUpload;

@IocBean
@Slf4j
public class FromSummaryComponent {

    @Inject
    private SysUserService sysUserService;
    @Inject
    private SqfwCompleteflowService sqfwCompleteflowService;
    @Inject
    private SqfwFormSummaryService sqfwFormSummaryService;
    @Inject
    private SqfwWebSocket sqfwWebSocket;
    @Inject
    private SqfwWorkorderService sqfwWorkorderService;
    @Inject
    private SqfwCenSusPaperService sqfwCenSusPaperService;

    // 添加表数据
    public SqfwFormSummaryWithFlowDTO addFromSummary(SqfwFormSummaryWithFlowDTO reqVo) {
        Sys_user sysUser = sysUserService.fetch(SecurityUtil.getUserId());
        SqfwCompleteFlowUpdateDTO completeFlow = reqVo.getCompleteFlow();
        Sqfw_formSummary sqfwFormSummary = reqVo.getFormSummary();
        Trans.exec(() -> {
            // 1 构建基本参数
            CommonComponent.buildBaseSqfwFormSummary(sqfwFormSummary);
            sqfwFormSummary.setType(SupportBusinessTypeEnum.MEET_RECORD.getName());
            // 首先现需要生成一个工作流信息
            completeFlow.setResourcePath("creating").setFileType(SupportBusinessTypeEnum.MEET_RECORD.getName()).setPhone(sysUser.getMobile());
            sqfwCompleteflowService.insertCompleteflow(completeFlow, sysUser);
            // 2 插入汇总表
            sqfwFormSummary.setSqfwFlowId(completeFlow.getId());
            sqfwFormSummary.setSqfwId(completeFlow.getSqfwId());
            sqfwFormSummaryService.insert(sqfwFormSummary);
            sqfwWorkorderService.updateLatestFlowRemarkWithCompleteFlow(completeFlow.getWorkerId(), completeFlow.getFileType(), false);
        });
        return reqVo;
    }

    /**
     * 生成pdf
     *
     * @param completeflowId 工作流iD
     */
    @Async
    public void generatePDF(String userId, String completeflowId, Map<String, Object> conentMap, String filePath, String fileName, WebSocketMsgDTO msgDTO) {
        // 1 获取数据
        Sqfw_completeflow completeflow = sqfwCompleteflowService.fetch(completeflowId);
        if (completeflow == null) {
            throw new AppException("任务流数据不存在");
        }
        Sys_user sysUser = sysUserService.fetch(userId);
        // 2 上传文档到服务器
        GenerateWordAndPdfUrlVO pdfUrlVo = CommonComponent.uploadPDF(conentMap, filePath, fileName, fileName);
        // 3 修改本地数据
        if (StringUtils.isNotEmpty(pdfUrlVo.getPdfUrl())) {
            completeflow.setResourcePath(pdfUrlVo.getPdfUrl());
            sqfwCompleteflowService.update(completeflow);
            sqfwWebSocket.sendMessage(sysUser.getId(), msgDTO);
            return;
        }
        completeflow.setResourcePath("error");
        sqfwCompleteflowService.update(completeflow);
    }

    /**
     * 构建参数类型
     *
     * @param formSummary
     * @param num
     * @param type
     * @return
     */
    public Map<String, Object> buildContent(Sqfw_formSummary formSummary, int num, String type) {
        if (SupportBusinessTypeEnum.MEET_RECORD.getName().equals(type)) {
            return buildMeetContent(formSummary, num);
        }
        return new HashMap<>();
    }

    /**
     * 生成台账
     *
     * @param excelMap 数据集合
     * @param filePath 文件路径
     * @param fileName 文件名称
     * @param type     图片存储类型
     * @return url
     */
    public static String generateExcelLedger(Map<String, Object> excelMap, String filePath, String fileName, String type) {
        String path = CommonFormOfficeUtils.getTemplatePathByOS(filePath);
        ExcelFileCreateParamBO excelFileCreateParam = new ExcelFileCreateParamBO();
        excelFileCreateParam.setTemplatePath(path);
        excelFileCreateParam.setSheetParam(excelMap);
        excelFileCreateParam.setDataList((List<Map<String, Object>>) excelMap.get("list"));
        if (SupportBusinessTypeEnum.MEET_RECORD.getName().equals(type)) {
            // 涉及图片需要修改这里
            excelFileCreateParam.setClazz(MeetFormExcelSNSQ.class);
        }
        if (SupportBusinessTypeEnum.HOUSE_SURVEY_FORM.getName().equals(type)) {
            excelFileCreateParam.setClazz(HouseSurveyFormExcelSNSQ.class);
        }
        excelFileCreateParam.setFileName(fileName);
        excelFileCreateParam.setReturnWebUrlFlag(true);
        return createExcelAndUpload(excelFileCreateParam);
    }

    private Map<String, Object> buildMeetContent(Sqfw_formSummary formSummary, int num) {
        Date fillDate = formSummary.getFillDate() == null ? formSummary.getCreateDate() : formSummary.getFillDate();
        MeetingMinutesTemplateVo reqVo = new MeetingMinutesTemplateVo();
        reqVo.setCommunity(formSummary.getCommunity())
                .setCreateBy(formSummary.getCreateUserName())
                .setA20(StrUtil.formatStr(formSummary.getA20()))
                .setA3(formSummary.getA3())
                .setA18(formSummary.getA18())
                .setNum(num)
                .setA9(null)
                .setA9s(null)
                .setFileDate(DateUtil.format(fillDate, DatePattern.CHINESE_DATE_PATTERN));
        // 将对象转为map
        Map<String, Object> paramMap = CommonComponent.entityToMap(reqVo);
        return paramMap;
    }

    /**
     * 入戶调查解析A7数据
     */
    public void addCenSusPaperByHouseSurveyForm(Sqfw_formSummary formSummary) {
        //拼接详细地址
        formSummary.setA15(StringUtils.isNotBlank(formSummary.getA15()) ? formSummary.getA15() : StrUtil.getHouseAddress(formSummary));

        if (StringUtils.isEmpty(formSummary.getA7())) {
            return;
        }
        List<Sqfw_cenSusPaper> paperList = sqfwCenSusPaperService.addOrUpdateByFormSummaryStr(formSummary.getA7(), formSummary);
        String paperA7Str = JSONObject.toJSONString(paperList);
        formSummary.setA7(paperA7Str);

        // 12-11号需求：将a7中‘姓名’‘证件号’‘手机号’‘特殊人员标识’‘备注’‘用户备注’内容存为json
        if (paperList != null && paperList.size() > 0) {
            List<Sqfw_cenSusPaper> sqfwCenSusPaperList = new ArrayList<>();
            for (Sqfw_cenSusPaper cenSusPaper : paperList) {
                Sqfw_cenSusPaper susPaper = new Sqfw_cenSusPaper();
                susPaper.setName(cenSusPaper.getName());
                susPaper.setCardId(cenSusPaper.getCardId());
                susPaper.setPhone(cenSusPaper.getPhone());
                susPaper.setSpecialMark(cenSusPaper.getSpecialMark());
                susPaper.setRemark(cenSusPaper.getRemark());
                susPaper.setUserNotes(cenSusPaper.getUserNotes());
                sqfwCenSusPaperList.add(susPaper);
            }
            formSummary.setParamData(JSONUtil.toJsonStr(sqfwCenSusPaperList));
            //拼接详细地址
            //formSummary.setA15(StringUtils.isNotBlank(formSummary.getA15()) ? formSummary.getA15() : StrUtil.getHouseAddress(formSummary));
        }
    }

    /**
     * 设置检查状态
     */
    public static void buildInspection(Sqfw_formSummary_new formSummary) {
        // 已停业不做任何修改
        if (StringUtils.isNotEmpty(formSummary.getCheckStatus())) {
            if (SqfwFormSummaryFieldEnum.CHECK_STATUS_CLOSED.getCode().equals(formSummary.getCheckStatus())) {
                throw new AppException("已停业，不能提交数据！");
            }
        }
        // 获取检查时间
        LocalDateTime start = LocalDateTime.now();
        Date fillDate = formSummary.getFillDate();
        if (fillDate != null) {
            start = fillDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        }
        Duration duration = Duration.between(start, LocalDateTime.now());
        // 超过30天设置为已超时
        formSummary.setCheckStatus(SqfwFormSummaryFieldEnum.check_status_init.getCode())
                .setInspectionSituation(duration.toDays() > 30 ? SqfwFormSummaryFieldEnum.CHECK_SITUATION_YES.getCode() :
                        SqfwFormSummaryFieldEnum.CHECK_SITUATION_NO.getCode());
    }

    public static PdfGenerateParam initPdfGenerateParam() {
        PdfGenerateParam pdfGenerateParam = new PdfGenerateParam();
        SysUserService userService = NutzIocUtils.getBean(SysUserService.class);
        Sys_user user = userService.fetch(SecurityUtil.getUserId());
        CommonParam createUserCommonParam = new CommonParam();
        createUserCommonParam
                .setCommunity(user.getCommunity())
//                .setCommunity("云潭街道")
                .setCreateUserId(user.getId())
                .setCreateUserName(user.getUsername())
                .setCreateUserPhone(user.getMobile()).setUnitId(user.getUnitId())
                .setUnitName(user.getUnitName());
        pdfGenerateParam.setCreateUserCommonParam(createUserCommonParam);
        // 提示为下载模板
        pdfGenerateParam.setDownTemplate(true);
        return pdfGenerateParam;
    }

    /**
     * 初始化基本参数
     *
     * @return
     */
    public static SqfwPdfCreateCommonBO initPdfSqfwPdfCreateCommonBOParam() {
        SqfwPdfCreateCommonBO basePdfParamDTO = new SqfwPdfCreateCommonBO();
        SysUserService userService = NutzIocUtils.getBean(SysUserService.class);
        Sys_user user = userService.fetch(SecurityUtil.getUserId());
        BasePdfParamDTO createUserCommonParam = new BasePdfParamDTO();
        createUserCommonParam.setCreateUserName(user.getUsername());
        createUserCommonParam.setCreateUserName(user.getUsername());
        createUserCommonParam.setCreateUserPhone(user.getMobile());
        createUserCommonParam.setProvince(user.getProvince());
        createUserCommonParam.setCity(user.getCity());
        createUserCommonParam.setDistrict(user.getDistrict());
        createUserCommonParam.setCounty(user.getCounty());
        createUserCommonParam.setCommunity(user.getCommunity());
        basePdfParamDTO.setBasePdfParamDTO(createUserCommonParam);
        // 提示为下载模板
        basePdfParamDTO.setDownTemplate(true);
        return basePdfParamDTO;
    }
}
